<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>Proposals for the future of CSS Paged Media</title>
  <meta content="UD" name="w3c-status">
  <link href="https://www.w3.org/StyleSheets/TR/2021/W3C-UD" rel="stylesheet">
  <link href="https://www.w3.org/2008/site/images/favicon.ico" rel="icon">
  <meta content="Bikeshed version afa1ee937, updated Fri Apr 28 15:57:36 2023 -0700" name="generator">
  <link href="https://drafts.csswg.org/css-page-4/" rel="canonical">
  <meta content="14a0f8c9e67bedd0fc65b691739f866ee36dd7bf" name="document-revision">
<style>/* style-autolinks */
.css.css, .property.property, .descriptor.descriptor {
    color: var(--a-normal-text);
    font-size: inherit;
    font-family: inherit;
}
.css::before, .property::before, .descriptor::before {
    content: "‘";
}
.css::after, .property::after, .descriptor::after {
    content: "’";
}
.property, .descriptor {
    /* Don't wrap property and descriptor names */
    white-space: nowrap;
}
.type { /* CSS value <type> */
    font-style: italic;
}
pre .property::before, pre .property::after {
    content: "";
}
[data-link-type="property"]::before,
[data-link-type="propdesc"]::before,
[data-link-type="descriptor"]::before,
[data-link-type="value"]::before,
[data-link-type="function"]::before,
[data-link-type="at-rule"]::before,
[data-link-type="selector"]::before,
[data-link-type="maybe"]::before {
    content: "‘";
}
[data-link-type="property"]::after,
[data-link-type="propdesc"]::after,
[data-link-type="descriptor"]::after,
[data-link-type="value"]::after,
[data-link-type="function"]::after,
[data-link-type="at-rule"]::after,
[data-link-type="selector"]::after,
[data-link-type="maybe"]::after {
    content: "’";
}

[data-link-type].production::before,
[data-link-type].production::after,
.prod [data-link-type]::before,
.prod [data-link-type]::after {
    content: "";
}

[data-link-type=element],
[data-link-type=element-attr] {
    font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace;
    font-size: .9em;
}
[data-link-type=element]::before { content: "<" }
[data-link-type=element]::after  { content: ">" }

[data-link-type=biblio] {
    white-space: pre;
}
</style>
<style>/* style-colors */

/* Any --*-text not paired with a --*-bg is assumed to have a transparent bg */
:root {
    color-scheme: light dark;

    --text: black;
    --bg: white;

    --unofficial-watermark: url(https://www.w3.org/StyleSheets/TR/2016/logos/UD-watermark);

    --logo-bg: #1a5e9a;
    --logo-active-bg: #c00;
    --logo-text: white;

    --tocnav-normal-text: #707070;
    --tocnav-normal-bg: var(--bg);
    --tocnav-hover-text: var(--tocnav-normal-text);
    --tocnav-hover-bg: #f8f8f8;
    --tocnav-active-text: #c00;
    --tocnav-active-bg: var(--tocnav-normal-bg);

    --tocsidebar-text: var(--text);
    --tocsidebar-bg: #f7f8f9;
    --tocsidebar-shadow: rgba(0,0,0,.1);
    --tocsidebar-heading-text: hsla(203,20%,40%,.7);

    --toclink-text: var(--text);
    --toclink-underline: #3980b5;
    --toclink-visited-text: var(--toclink-text);
    --toclink-visited-underline: #054572;

    --heading-text: #005a9c;

    --hr-text: var(--text);

    --algo-border: #def;

    --del-text: red;
    --del-bg: transparent;
    --ins-text: #080;
    --ins-bg: transparent;

    --a-normal-text: #034575;
    --a-normal-underline: #bbb;
    --a-visited-text: var(--a-normal-text);
    --a-visited-underline: #707070;
    --a-hover-bg: rgba(75%, 75%, 75%, .25);
    --a-active-text: #c00;
    --a-active-underline: #c00;

    --blockquote-border: silver;
    --blockquote-bg: transparent;
    --blockquote-text: currentcolor;

    --issue-border: #e05252;
    --issue-bg: #fbe9e9;
    --issue-text: var(--text);
    --issueheading-text: #831616;

    --example-border: #e0cb52;
    --example-bg: #fcfaee;
    --example-text: var(--text);
    --exampleheading-text: #574b0f;

    --note-border: #52e052;
    --note-bg: #e9fbe9;
    --note-text: var(--text);
    --noteheading-text: hsl(120, 70%, 30%);
    --notesummary-underline: silver;

    --assertion-border: #aaa;
    --assertion-bg: #eee;
    --assertion-text: black;

    --advisement-border: orange;
    --advisement-bg: #fec;
    --advisement-text: var(--text);
    --advisementheading-text: #b35f00;

    --warning-border: red;
    --warning-bg: hsla(40,100%,50%,0.95);
    --warning-text: var(--text);

    --amendment-border: #330099;
    --amendment-bg: #F5F0FF;
    --amendment-text: var(--text);
    --amendmentheading-text: #220066;

    --def-border: #8ccbf2;
    --def-bg: #def;
    --def-text: var(--text);
    --defrow-border: #bbd7e9;

    --datacell-border: silver;

    --indexinfo-text: #707070;

    --indextable-hover-text: black;
    --indextable-hover-bg: #f7f8f9;

    --outdatedspec-bg: rgba(0, 0, 0, .5);
    --outdatedspec-text: black;
    --outdated-bg: maroon;
    --outdated-text: white;
    --outdated-shadow: red;

    --editedrec-bg: darkorange;
}
</style>
<style>/* style-counters */
body {
    counter-reset: example figure issue;
}
.issue {
    counter-increment: issue;
}
.issue:not(.no-marker)::before {
    content: "Issue " counter(issue);
}

.example {
    counter-increment: example;
}
.example:not(.no-marker)::before {
    content: "Example " counter(example);
}
.invalid.example:not(.no-marker)::before,
.illegal.example:not(.no-marker)::before {
    content: "Invalid Example" counter(example);
}

figcaption {
    counter-increment: figure;
}
figcaption:not(.no-marker)::before {
    content: "Figure " counter(figure) " ";
}
</style>
<style>/* style-dfn-panel */
:root {
    --dfnpanel-bg: #ddd;
    --dfnpanel-text: var(--text);
}
.dfn-panel {
    position: absolute;
    z-index: 35;
    width: 20em;
    width: 300px;
    height: auto;
    max-height: 500px;
    overflow: auto;
    padding: 0.5em 0.75em;
    font: small Helvetica Neue, sans-serif, Droid Sans Fallback;
    background: var(--dfnpanel-bg);
    color: var(--dfnpanel-text);
    border: outset 0.2em;
    white-space: normal; /* in case it's moved into a pre */
}
.dfn-panel:not(.on) { display: none; }
.dfn-panel * { margin: 0; padding: 0; text-indent: 0; }
.dfn-panel > b { display: block; }
.dfn-panel a { color: var(--dfnpanel-text); }
.dfn-panel a:not(:hover) { text-decoration: none !important; border-bottom: none !important; }
.dfn-panel > b + b { margin-top: 0.25em; }
.dfn-panel ul { padding: 0 0 0 1em; list-style: none; }
.dfn-panel li a {
    white-space: pre;
    display: inline-block;
    max-width: calc(300px - 1.5em - 1em);
    overflow: hidden;
    text-overflow: ellipsis;
}

.dfn-panel.activated {
    display: inline-block;
    position: fixed;
    left: .5em;
    bottom: 2em;
    margin: 0 auto;
    max-width: calc(100vw - 1.5em - .4em - .5em);
    max-height: 30vh;
}

.dfn-paneled[role="button"] { cursor: pointer; }
</style>
<style>/* style-issues */
a[href].issue-return {
    float: right;
    float: inline-end;
    color: var(--issueheading-text);
    font-weight: bold;
    text-decoration: none;
}
</style>
<style>/* style-md-lists */
/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}
</style>
<style>/* style-selflinks */

:root {
    --selflink-text: white;
    --selflink-bg: gray;
    --selflink-hover-text: black;
}
.heading, .issue, .note, .example, li, dt {
    position: relative;
}
a.self-link {
    position: absolute;
    top: 0;
    left: calc(-1 * (3.5rem - 26px));
    width: calc(3.5rem - 26px);
    height: 2em;
    text-align: center;
    border: none;
    transition: opacity .2s;
    opacity: .5;
}
a.self-link:hover {
    opacity: 1;
}
.heading > a.self-link {
    font-size: 83%;
}
.example > a.self-link,
.note > a.self-link,
.issue > a.self-link {
    /* These blocks are overflow:auto, so positioning outside
       doesn't work. */
    left: auto;
    right: 0;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: var(--selflink-bg);
    color: var(--selflink-text);
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: var(--selflink-hover-text);
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }
</style>
<style>/* style-darkmode */

@media (prefers-color-scheme: dark) {
    :root {
        --text: #ddd;
        --bg: black;

        --unofficial-watermark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cg fill='%23100808' transform='translate(200 200) rotate(-45) translate(-200 -200)' stroke='%23100808' stroke-width='3'%3E%3Ctext x='50%25' y='220' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EUNOFFICIAL%3C/text%3E%3Ctext x='50%25' y='305' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EDRAFT%3C/text%3E%3C/g%3E%3C/svg%3E");

        --logo-bg: #1a5e9a;
        --logo-active-bg: #c00;
        --logo-text: white;

        --tocnav-normal-text: #999;
        --tocnav-normal-bg: var(--bg);
        --tocnav-hover-text: var(--tocnav-normal-text);
        --tocnav-hover-bg: #080808;
        --tocnav-active-text: #f44;
        --tocnav-active-bg: var(--tocnav-normal-bg);

        --tocsidebar-text: var(--text);
        --tocsidebar-bg: #080808;
        --tocsidebar-shadow: rgba(255,255,255,.1);
        --tocsidebar-heading-text: hsla(203,20%,40%,.7);

        --toclink-text: var(--text);
        --toclink-underline: #6af;
        --toclink-visited-text: var(--toclink-text);
        --toclink-visited-underline: #054572;

        --heading-text: #8af;

        --hr-text: var(--text);

        --algo-border: #456;

        --del-text: #f44;
        --del-bg: transparent;
        --ins-text: #4a4;
        --ins-bg: transparent;

        --a-normal-text: #6af;
        --a-normal-underline: #555;
        --a-visited-text: var(--a-normal-text);
        --a-visited-underline: var(--a-normal-underline);
        --a-hover-bg: rgba(25%, 25%, 25%, .2);
        --a-active-text: #f44;
        --a-active-underline: var(--a-active-text);

        --borderedblock-bg: rgba(255, 255, 255, .05);

        --blockquote-border: silver;
        --blockquote-bg: var(--borderedblock-bg);
        --blockquote-text: currentcolor;

        --issue-border: #e05252;
        --issue-bg: var(--borderedblock-bg);
        --issue-text: var(--text);
        --issueheading-text: hsl(0deg, 70%, 70%);

        --example-border: hsl(50deg, 90%, 60%);
        --example-bg: var(--borderedblock-bg);
        --example-text: var(--text);
        --exampleheading-text: hsl(50deg, 70%, 70%);

        --note-border: hsl(120deg, 100%, 35%);
        --note-bg: var(--borderedblock-bg);
        --note-text: var(--text);
        --noteheading-text: hsl(120, 70%, 70%);
        --notesummary-underline: silver;

        --assertion-border: #444;
        --assertion-bg: var(--borderedblock-bg);
        --assertion-text: var(--text);

        --advisement-border: orange;
        --advisement-bg: #222218;
        --advisement-text: var(--text);
        --advisementheading-text: #f84;

        --warning-border: red;
        --warning-bg: hsla(40,100%,20%,0.95);
        --warning-text: var(--text);

        --amendment-border: #330099;
        --amendment-bg: #080010;
        --amendment-text: var(--text);
        --amendmentheading-text: #cc00ff;

        --def-border: #8ccbf2;
        --def-bg: #080818;
        --def-text: var(--text);
        --defrow-border: #136;

        --datacell-border: silver;

        --indexinfo-text: #aaa;

        --indextable-hover-text: var(--text);
        --indextable-hover-bg: #181818;

        --outdatedspec-bg: rgba(255, 255, 255, .5);
        --outdatedspec-text: black;
        --outdated-bg: maroon;
        --outdated-text: white;
        --outdated-shadow: red;

        --editedrec-bg: darkorange;
    }
    /* In case a transparent-bg image doesn't expect to be on a dark bg,
       which is quite common in practice... */
    img { background: white; }
}

@media (prefers-color-scheme: dark) {
    :root {
        --selflink-text: black;
        --selflink-bg: silver;
        --selflink-hover-text: white;
    }
}

@media (prefers-color-scheme: dark) {
    :root {
        --dfnpanel-bg: #222;
        --dfnpanel-text: var(--text);
    }
}
</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"><a class="logo" href="https://www.w3.org/"> <img alt="W3C" height="48" src="https://www.w3.org/StyleSheets/TR/2021/logos/W3C" width="72"> </a> </p>
   <h1 class="p-name no-ref" id="title">Proposals for the future of CSS Paged Media</h1>
   <p id="w3c-state"><a href="https://www.w3.org/standards/types#UD">Unofficial Proposal Draft</a>, <time class="dt-updated" datetime="2023-05-12">12 May 2023</time></p>
   <details open>
    <summary>More details about this document</summary>
    <div data-fill-with="spec-metadata">
     <dl>
      <dt>This version:
      <dd><a class="u-url" href="https://drafts.csswg.org/css-page-4/">https://drafts.csswg.org/css-page-4/</a>
      <dt>Issue Tracking:
      <dd><a href="https://github.com/w3c/csswg-drafts/labels/css-page-4">CSSWG Issues Repository</a>
      <dt class="editor">Editor:
      <dd class="editor p-author h-card vcard"><span class="p-name fn">Daniel Glazman</span> (<span class="p-org org">Disruptive Innovations</span>)
      <dt>Suggest an Edit for this Spec:
      <dd><a href="https://github.com/w3c/csswg-drafts/blob/main/css-page-4/Overview.bs">GitHub Editor</a>
     </dl>
    </div>
   </details>
   <div data-fill-with="warning"></div>
   <p class="copyright" data-fill-with="copyright"><a href="https://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © 2023 <a href="https://www.w3.org/">World Wide Web Consortium</a>. <abbr title="World Wide Web Consortium">W3C</abbr><sup>®</sup> <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a href="https://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and <a href="https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document" rel="license">permissive document license</a> rules apply. </p>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>A list of issues with the current CSS page model, and possibly directions to explore for fixing it.</p>
    <a href="https://www.w3.org/TR/CSS/">CSS</a> is a language for describing the rendering of structured documents
(such as HTML and XML)
on screen, on paper, etc. 
  </div>
  <h2 class="no-num no-toc no-ref heading settled" id="sotd"><span class="content">Status of this document</span></h2>
  <div data-fill-with="status">
   <p><em>This section describes the status of this document at the time of its publication.
	A list of current W3C publications
	and the latest revision of this technical report
	can be found in the <a href="https://www.w3.org/TR/">W3C technical reports index at https://www.w3.org/TR/.</a></em> </p>
   <p>Please send feedback
	by <a href="https://github.com/w3c/csswg-drafts/issues">filing issues in GitHub</a> (preferred),
	including the spec code “css-page” in the title, like this:
	“[css-page] <i>…summary of comment…</i>”.
	All issues and comments are <a href="https://lists.w3.org/Archives/Public/public-css-archive/">archived</a>.
	Alternately, feedback can be sent to the (<a href="https://lists.w3.org/Archives/Public/www-style/">archived</a>) public mailing list <a href="mailto:www-style@w3.org?Subject=%5Bcss-page%5D%20PUT%20SUBJECT%20HERE">www-style@w3.org</a>. </p>
   <p>This document is governed by the <a href="https://www.w3.org/2021/Process-20211102/" id="w3c_process_revision">2 November 2021 W3C Process Document</a>. </p>
   <p>This document was produced by a group operating under the <a href="https://www.w3.org/Consortium/Patent-Policy-20200915/">W3C Patent Policy</a>.
	W3C maintains a <a href="https://www.w3.org/groups/wg/css/ipr" rel="disclosure">public list of any patent disclosures</a> made in connection with the deliverables of the group;
	that page also includes instructions for disclosing a patent.
	An individual who has actual knowledge of a patent which the individual believes
	contains <a href="https://www.w3.org/Consortium/Patent-Policy-20200915/#def-essential">Essential Claim(s)</a> must disclose the information in accordance with <a href="https://www.w3.org/Consortium/Patent-Policy-20200915/#sec-Disclosure">section 6 of the W3C Patent Policy</a>. </p>
   <p></p>
  </div>
  <div data-fill-with="at-risk"></div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li><a href="#css-page-model"><span class="secno">1</span> <span class="content">The CSS 3 Page Model</span></a>
    <li>
     <a href="#w3c-conformance"><span class="secno"></span> <span class="content"> Conformance</span></a>
     <ol class="toc">
      <li><a href="#w3c-conventions"><span class="secno"></span> <span class="content"> Document conventions</span></a>
      <li><a href="#w3c-conformance-classes"><span class="secno"></span> <span class="content"> Conformance classes</span></a>
      <li>
       <a href="#w3c-partial"><span class="secno"></span> <span class="content"> Partial implementations</span></a>
       <ol class="toc">
        <li><a href="#w3c-conform-future-proofing"><span class="secno"></span> <span class="content"> Implementations of Unstable and Proprietary Features</span></a>
       </ol>
      <li><a href="#w3c-testing"><span class="secno"></span> <span class="content"> Non-experimental implementations</span></a>
     </ol>
    <li>
     <a href="#index"><span class="secno"></span> <span class="content">Index</span></a>
     <ol class="toc">
      <li><a href="#index-defined-here"><span class="secno"></span> <span class="content">Terms defined by this specification</span></a>
      <li><a href="#index-defined-elsewhere"><span class="secno"></span> <span class="content">Terms defined by reference</span></a>
     </ol>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#normative"><span class="secno"></span> <span class="content">Normative References</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="css-page-model"><span class="secno">1. </span><span class="content">The CSS 3 Page Model</span><a class="self-link" href="#css-page-model"></a></h2>
   <p>This section is informative.</p>
   <p>The current Page Model,
as described in <cite>CSS3 Module: Paged Media </cite><a data-link-type="biblio" href="#biblio-css3page" title="CSS Paged Media Module Level 3">[CSS3PAGE]</a>,
is the following one:
the printable area of a page,
the <dfn data-dfn-type="dfn" data-noexport id="page-box">page box<a class="self-link" href="#page-box"></a></dfn>,
is made of one page box itself divided in four areas:</p>
   <figure>
     <img alt="CSS 3 Paged Media’s page model" height="266" src="PageBox.png" width="267"> 
    <figcaption>The CSS3 Page Model</figcaption>
   </figure>
   <ol>
    <li data-md>
     <p>the <dfn data-dfn-type="dfn" data-noexport id="page-margin">page margin<a class="self-link" href="#page-margin"></a></dfn>;
that area is itself divided into 16 <dfn data-dfn-type="dfn" data-noexport id="page-margin-boxes">page-margin boxes<a class="self-link" href="#page-margin-boxes"></a></dfn> (@top-left-corner, @top-left, @top-center, etc. )</p>
     <figure>
       <img alt="CSS 3 page-margin boxes" height="226" src="RightMarginBoxes.png" width="181"> 
      <figcaption>The 16 page-margin boxes<br> (with highlight of 3 of them)<br> </figcaption>
     </figure>
    <li data-md>
     <p>the <dfn data-dfn-type="dfn" data-noexport id="page-border">page border<a class="self-link" href="#page-border"></a></dfn></p>
    <li data-md>
     <p>the <dfn data-dfn-type="dfn" data-noexport id="page-padding">page padding<a class="self-link" href="#page-padding"></a></dfn></p>
    <li data-md>
     <p>and finally the <dfn data-dfn-type="dfn" data-noexport id="page-area">page area<a class="self-link" href="#page-area"></a></dfn> containing the boxes generated by
the flow of the main contents of the document.</p>
   </ol>
   <p>It’s is possible to flow content,
for instance page headers and footers or footnotes,
into a page-margin box
using features introduced by the <cite>CSS Generated Content for Paged Media Module </cite><a data-link-type="biblio" href="#biblio-css3gcpm" title="CSS Generated Content for Paged Media Module">[CSS3GCPM]</a>.</p>
   <p>It is also possible to define multiple page templates for a single document
using the <span class="css">@page</span> at-rule
that allows to select the
first page, left pages, right pages or named pages of a paginated flow.</p>
   <p>If this page model allowed the publishing industry to adopt HTML and CSS as pivot formats,
it starts showing its limits for the following reasons:</p>
   <ul>
    <li data-md>
     <p>the 16 page-margin boxes are an extension
of the print features offered by desktop browsers.
Desktop browsers usually offer control over 6 page-margin boxes only.
Only one desktop browser claims implementation
of the page model described above in the fourteen last years.
The other desktop browsers' control over the 6 page-margin boxes
is then not achieved through the cascade of CSS UA stylesheets.</p>
    <li data-md>
     <p>no editing environment available on the market
and in particular Wysiwyg text editor
(for instance like Microsoft Word)
implements such a box model.</p>
    <li data-md>
     <p>it’s not possible with the current model to position headers and footers
(for instance the HTML5 header and footer elements)
arbitrarily in the page area.</p>
    <li data-md>
     <p>the <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-page-3/#at-ruledef-page" id="ref-for-at-ruledef-page">@page</a> at-rule currently allows nested at-rules
only for the definition of page-margin boxes.
Similarly, the set of CSS properties applicable to a page box
is limited and it is impossible in this model to use <cite>CSS Regions Module Level 3</cite> <a data-link-type="biblio" href="#biblio-css3-regions" title="CSS Regions Module Level 1">[CSS3-REGIONS]</a> to flow content into a given predefined area of a page,
exclude an area from the page using <cite>CSS 3 Exclusions and Shapes Module</cite> <a data-link-type="biblio" href="#biblio-css3-exclusions" title="CSS Exclusions Module Level 1">[CSS3-EXCLUSIONS]</a>,
lay out the page area into a grid using <cite>CSS Grid Layout</cite> <a data-link-type="biblio" href="#biblio-css3-grid-layout" title="CSS Grid Layout Module Level 1">[CSS3-GRID-LAYOUT]</a> or using <span class="css">''@slot</span> rules
that were discussed multiple times by the CSS Working Group
in the recent past.
The successful electronic book editing environment of Apple Inc.,
iBooks Author,
already allows <span class="css" id="ref-for-at-ruledef-page①">@page</span> rules to specify
arbitrary slots,
arbitrary exclusions and shapes,
and extends the list of applicable properties;
most of its advanced layout capabilities are based on these features.</p>
    <li data-md>
     <p>the <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-page-3/#at-ruledef-page" id="ref-for-at-ruledef-page②">@page</a> rule of <cite>CSS 2.1</cite> <a data-link-type="biblio" href="#biblio-css21" title="Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification">[CSS21]</a> is intended for use on print media,
not dynamic media.
The spread of complex HTML-based slideshows and electronic book viewers
has shown that the Page Model should also apply to screen media and alike.</p>
    <li data-md>
     <p>++TBD</p>
   </ul>
  </main>
  <h2 class="no-ref no-num heading settled" id="w3c-conformance"><span class="content"> Conformance</span><a class="self-link" href="#w3c-conformance"></a></h2>
  <h3 class="no-ref heading settled" id="w3c-conventions"><span class="content"> Document conventions</span><a class="self-link" href="#w3c-conventions"></a></h3>
  <p>Conformance requirements are expressed with a combination of
    descriptive assertions and RFC 2119 terminology. The key words “MUST”,
    “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”,
    “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this
    document are to be interpreted as described in RFC 2119.
    However, for readability, these words do not appear in all uppercase
    letters in this specification. </p>
  <p>All of the text of this specification is normative except sections
    explicitly marked as non-normative, examples, and notes. <a data-link-type="biblio" href="#biblio-rfc2119" title="Key words for use in RFCs to Indicate Requirement Levels">[RFC2119]</a></p>
  <p>Examples in this specification are introduced with the words “for example”
    or are set apart from the normative text with <code>class="example"</code>,
    like this: </p>
  <div class="example" id="w3c-example">
   <a class="self-link" href="#w3c-example"></a> 
   <p>This is an example of an informative example.</p>
  </div>
  <p>Informative notes begin with the word “Note” and are set apart from the
    normative text with <code>class="note"</code>, like this: </p>
  <p class="note" role="note">Note, this is an informative note.</p>
  <p>Advisements are normative sections styled to evoke special attention and are
    set apart from other normative text with <code>&lt;strong class="advisement"></code>, like
    this: <strong class="advisement"> UAs MUST provide an accessible alternative. </strong></p>
  <h3 class="no-ref heading settled" id="w3c-conformance-classes"><span class="content"> Conformance classes</span><a class="self-link" href="#w3c-conformance-classes"></a></h3>
  <p>Conformance to this specification
    is defined for three conformance classes: </p>
  <dl>
   <dt>style sheet 
   <dd>A <a href="http://www.w3.org/TR/CSS21/conform.html#style-sheet">CSS
            style sheet</a>. 
   <dt>renderer 
   <dd>A <a href="http://www.w3.org/TR/CSS21/conform.html#user-agent">UA</a> that interprets the semantics of a style sheet and renders
            documents that use them. 
   <dt>authoring tool 
   <dd>A <a href="http://www.w3.org/TR/CSS21/conform.html#user-agent">UA</a> that writes a style sheet. 
  </dl>
  <p>A style sheet is conformant to this specification
    if all of its statements that use syntax defined in this module are valid
    according to the generic CSS grammar and the individual grammars of each
    feature defined in this module. </p>
  <p>A renderer is conformant to this specification
    if, in addition to interpreting the style sheet as defined by the
    appropriate specifications, it supports all the features defined
    by this specification by parsing them correctly
    and rendering the document accordingly. However, the inability of a
    UA to correctly render a document due to limitations of the device
    does not make the UA non-conformant. (For example, a UA is not
    required to render color on a monochrome monitor.) </p>
  <p>An authoring tool is conformant to this specification
    if it writes style sheets that are syntactically correct according to the
    generic CSS grammar and the individual grammars of each feature in
    this module, and meet all other conformance requirements of style sheets
    as described in this module. </p>
  <h3 class="no-ref heading settled" id="w3c-partial"><span class="content"> Partial implementations</span><a class="self-link" href="#w3c-partial"></a></h3>
  <p>So that authors can exploit the forward-compatible parsing rules to
    assign fallback values, CSS renderers <strong>must</strong> treat as invalid (and <a href="http://www.w3.org/TR/CSS21/conform.html#ignore">ignore
    as appropriate</a>) any at-rules, properties, property values, keywords,
    and other syntactic constructs for which they have no usable level of
    support. In particular, user agents <strong>must not</strong> selectively
    ignore unsupported component values and honor supported values in a single
    multi-value property declaration: if any value is considered invalid
    (as unsupported values must be), CSS requires that the entire declaration
    be ignored.</p>
  <h4 class="heading settled" id="w3c-conform-future-proofing"><span class="content"> Implementations of Unstable and Proprietary Features</span><a class="self-link" href="#w3c-conform-future-proofing"></a></h4>
  <p>To avoid clashes with future stable CSS features,
        the CSSWG recommends <a href="http://www.w3.org/TR/CSS/#future-proofing">following best practices</a> for the implementation of <a href="http://www.w3.org/TR/CSS/#unstable">unstable</a> features and <a href="http://www.w3.org/TR/CSS/#proprietary-extension">proprietary extensions</a> to CSS. </p>
  <h3 class="no-ref heading settled" id="w3c-testing"><span class="content"> Non-experimental implementations</span><a class="self-link" href="#w3c-testing"></a></h3>
  <p>Once a specification reaches the Candidate Recommendation stage,
    non-experimental implementations are possible, and implementors should
    release an unprefixed implementation of any CR-level feature they
    can demonstrate to be correctly implemented according to spec. </p>
  <p>To establish and maintain the interoperability of CSS across
    implementations, the CSS Working Group requests that non-experimental
    CSS renderers submit an implementation report (and, if necessary, the
    testcases used for that implementation report) to the W3C before
    releasing an unprefixed implementation of any CSS features. Testcases
    submitted to W3C are subject to review and correction by the CSS
    Working Group. </p>
  <p>Further information on submitting testcases and implementation reports
    can be found from on the CSS Working Group’s website at <a href="http://www.w3.org/Style/CSS/Test/">http://www.w3.org/Style/CSS/Test/</a>.
    Questions should be directed to the <a href="http://lists.w3.org/Archives/Public/public-css-testsuite">public-css-testsuite@w3.org</a> mailing list.</p>
<script src="https://www.w3.org/scripts/TR/2021/fixup.js"></script>
  <h2 class="no-num no-ref heading settled" id="index"><span class="content">Index</span><a class="self-link" href="#index"></a></h2>
  <h3 class="no-num no-ref heading settled" id="index-defined-here"><span class="content">Terms defined by this specification</span><a class="self-link" href="#index-defined-here"></a></h3>
  <ul class="index">
   <li><a href="#page-area">page area</a><span>, in § 1</span>
   <li><a href="#page-border">page border</a><span>, in § 1</span>
   <li><a href="#page-box">page box</a><span>, in § 1</span>
   <li><a href="#page-margin">page margin</a><span>, in § 1</span>
   <li><a href="#page-margin-boxes">page-margin boxes</a><span>, in § 1</span>
   <li><a href="#page-padding">page padding</a><span>, in § 1</span>
  </ul>
  <h3 class="no-num no-ref heading settled" id="index-defined-elsewhere"><span class="content">Terms defined by reference</span><a class="self-link" href="#index-defined-elsewhere"></a></h3>
  <ul class="index">
   <li>
    <a data-link-type="biblio">[CSS3PAGE]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="5ee7eb9e">@page</span>
    </ul>
  </ul>
  <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2>
  <h3 class="no-num no-ref heading settled" id="normative"><span class="content">Normative References</span><a class="self-link" href="#normative"></a></h3>
  <dl>
   <dt id="biblio-css21">[CSS21]
   <dd>Bert Bos; et al. <a href="https://drafts.csswg.org/css2/"><cite>Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification</cite></a>. URL: <a href="https://drafts.csswg.org/css2/">https://drafts.csswg.org/css2/</a>
   <dt id="biblio-css3-exclusions">[CSS3-EXCLUSIONS]
   <dd>Rossen Atanassov; Vincent Hardy; Alan Stearns. <a href="https://drafts.csswg.org/css-exclusions/"><cite>CSS Exclusions Module Level 1</cite></a>. URL: <a href="https://drafts.csswg.org/css-exclusions/">https://drafts.csswg.org/css-exclusions/</a>
   <dt id="biblio-css3-grid-layout">[CSS3-GRID-LAYOUT]
   <dd>Tab Atkins Jr.; et al. <a href="https://drafts.csswg.org/css-grid/"><cite>CSS Grid Layout Module Level 1</cite></a>. URL: <a href="https://drafts.csswg.org/css-grid/">https://drafts.csswg.org/css-grid/</a>
   <dt id="biblio-css3-regions">[CSS3-REGIONS]
   <dd>Rossen Atanassov; Alan Stearns. <a href="https://drafts.csswg.org/css-regions/"><cite>CSS Regions Module Level 1</cite></a>. URL: <a href="https://drafts.csswg.org/css-regions/">https://drafts.csswg.org/css-regions/</a>
   <dt id="biblio-css3gcpm">[CSS3GCPM]
   <dd>Dave Cramer. <a href="https://drafts.csswg.org/css-gcpm/"><cite>CSS Generated Content for Paged Media Module</cite></a>. URL: <a href="https://drafts.csswg.org/css-gcpm/">https://drafts.csswg.org/css-gcpm/</a>
   <dt id="biblio-css3page">[CSS3PAGE]
   <dd>Elika Etemad; Simon Sapin. <a href="https://drafts.csswg.org/css-page-3/"><cite>CSS Paged Media Module Level 3</cite></a>. URL: <a href="https://drafts.csswg.org/css-page-3/">https://drafts.csswg.org/css-page-3/</a>
   <dt id="biblio-rfc2119">[RFC2119]
   <dd>S. Bradner. <a href="https://datatracker.ietf.org/doc/html/rfc2119"><cite>Key words for use in RFCs to Indicate Requirement Levels</cite></a>. March 1997. Best Current Practice. URL: <a href="https://datatracker.ietf.org/doc/html/rfc2119">https://datatracker.ietf.org/doc/html/rfc2119</a>
  </dl>
<script>/* script-dfn-panel */
"use strict";
{
    const dfnsJson = window.dfnsJson || {};

    function genDfnPanel({dfnID, url, dfnText, refSections, external}) {
        return mk.aside({
            class: "dfn-panel",
            id: `infopanel-for-${dfnID}`,
            "data-for": dfnID,
            "aria-labelled-by":`infopaneltitle-for-${dfnID}`,
            },
            mk.span({id:`infopaneltitle-for-${dfnID}`, style:"display:none"},
                `Info about the '${dfnText}' ${external?"external":""} reference.`),
            mk.a({href:url}, url),
            mk.b({}, "Referenced in:"),
            mk.ul({},
                ...refSections.map(section=>
                    mk.li({},
                        ...section.refs.map((ref, refI)=>
                            [
                                mk.a({
                                    href: `#${ref.id}`
                                    },
                                    (refI == 0) ? section.title : `(${refI + 1})`
                                ),
                                " ",
                            ]
                        ),
                    ),
                ),
            ),
        );
    }

    function genAllDfnPanels() {
        for(const panelData of Object.values(window.dfnpanelData)) {
            const dfnID = panelData.dfnID;
            const dfn = document.getElementById(dfnID);
            if(!dfn) {
                console.log(`Can't find dfn#${dfnID}.`, panelData);
            } else {
                const panel = genDfnPanel(panelData);
                append(document.body, panel);
                insertDfnPopupAction(dfn, panel)
            }
        }
    }

    document.addEventListener("DOMContentLoaded", ()=>{
        genAllDfnPanels();

        // Add popup behavior to all dfns to show the corresponding dfn-panel.
        var dfns = queryAll('.dfn-paneled');
        for(let dfn of dfns) { ; }

        document.body.addEventListener("click", (e) => {
            // If not handled already, just hide all dfn panels.
            hideAllDfnPanels();
        });
    })


    function hideAllDfnPanels() {
        // Turn off any currently "on" or "activated" panels.
        queryAll(".dfn-panel.on, .dfn-panel.activated").forEach(el=>hideDfnPanel(el));
    }

    function showDfnPanel(dfnPanel, dfn) {
        hideAllDfnPanels(); // Only display one at this time.
        dfn.setAttribute("aria-expanded", "true");
        dfnPanel.classList.add("on");
        dfnPanel.style.left = "5px";
        dfnPanel.style.top = "0px";
        const panelRect = dfnPanel.getBoundingClientRect();
        const panelWidth = panelRect.right - panelRect.left;
        if (panelRect.right > document.body.scrollWidth) {
            // Panel's overflowing the screen.
            // Just drop it below the dfn and flip it rightward instead.
            // This still wont' fix things if the screen is *really* wide,
            // but fixing that's a lot harder without 'anchor()'.
            dfnPanel.style.top = "1.5em";
            dfnPanel.style.left = "auto";
            dfnPanel.style.right = "0px";
        }
    }

    function pinDfnPanel(dfnPanel) {
        // Switch it to "activated" state, which pins it.
        dfnPanel.classList.add("activated");
        dfnPanel.style.left = null;
        dfnPanel.style.top = null;
    }

    function hideDfnPanel(dfnPanel, dfn) {
        if(!dfn) {
            dfn = document.getElementById(dfnPanel.getAttribute("data-for"));
        }
        dfn.setAttribute("aria-expanded", "false")
        dfnPanel.classList.remove("on");
        dfnPanel.classList.remove("activated");
    }

    function toggleDfnPanel(dfnPanel, dfn) {
        if(dfnPanel.classList.contains("on")) {
            hideDfnPanel(dfnPanel, dfn);
        } else {
            showDfnPanel(dfnPanel, dfn);
        }
    }

    function insertDfnPopupAction(dfn, dfnPanel) {
        // Find dfn panel
        const panelWrapper = document.createElement('span');
        panelWrapper.appendChild(dfnPanel);
        panelWrapper.style.position = "relative";
        panelWrapper.style.height = "0px";
        dfn.insertAdjacentElement("afterend", panelWrapper);
        dfn.setAttribute('role', 'button');
        dfn.setAttribute('aria-expanded', 'false')
        dfn.tabIndex = 0;
        dfn.classList.add('has-dfn-panel');
        dfn.addEventListener('click', (event) => {
            showDfnPanel(dfnPanel, dfn);
            event.stopPropagation();
        });
        dfn.addEventListener('keypress', (event) => {
            const kc = event.keyCode;
            // 32->Space, 13->Enter
            if(kc == 32 || kc == 13) {
                toggleDfnPanel(dfnPanel, dfn);
                event.stopPropagation();
                event.preventDefault();
            }
        });

        dfnPanel.addEventListener('click', (event) => {
            if (event.target.nodeName == 'A') {
                pinDfnPanel(dfnPanel);
            }
            event.stopPropagation();
        });

        dfnPanel.addEventListener('keydown', (event) => {
            if(event.keyCode == 27) { // Escape key
                hideDfnPanel(dfnPanel, dfn);
                event.stopPropagation();
                event.preventDefault();
            }
        })
    }
}
</script>
<script>/* script-dfn-panel-json */
window.dfnpanelData = {};
window.dfnpanelData['5ee7eb9e'] = {"dfnID": "5ee7eb9e", "url": "https://drafts.csswg.org/css-page-3/#at-ruledef-page", "dfnText": "@page", "refSections": [{"refs": [{"id": "ref-for-at-ruledef-page"}, {"id": "ref-for-at-ruledef-page\u2460"}, {"id": "ref-for-at-ruledef-page\u2461"}], "title": "1. The CSS 3 Page Model"}], "external": true};
</script>
<script>/* script-dom-helper */
function query(sel) { return document.querySelector(sel); }

function queryAll(sel) { return [...document.querySelectorAll(sel)]; }

function iter(obj) {
	if(!obj) return [];
	var it = obj[Symbol.iterator];
	if(it) return it;
	return Object.entries(obj);
}

function mk(tagname, attrs, ...children) {
	const el = document.createElement(tagname);
	for(const [k,v] of iter(attrs)) {
		if(k.slice(0,3) == "_on") {
			const eventName = k.slice(3);
			el.addEventListener(eventName, v);
		} else if(k[0] == "_") {
			// property, not attribute
			el[k.slice(1)] = v;
		} else {
			if(v === false || v == null) {
        continue;
      } else if(v === true) {
        el.setAttribute(k, "");
        continue;
      } else {
  			el.setAttribute(k, v);
      }
		}
	}
	append(el, children);
	return el;
}

/* Create shortcuts for every known HTML element */
[
  "a",
  "abbr",
  "acronym",
  "address",
  "applet",
  "area",
  "article",
  "aside",
  "audio",
  "b",
  "base",
  "basefont",
  "bdo",
  "big",
  "blockquote",
  "body",
  "br",
  "button",
  "canvas",
  "caption",
  "center",
  "cite",
  "code",
  "col",
  "colgroup",
  "datalist",
  "dd",
  "del",
  "details",
  "dfn",
  "dialog",
  "div",
  "dl",
  "dt",
  "em",
  "embed",
  "fieldset",
  "figcaption",
  "figure",
  "font",
  "footer",
  "form",
  "frame",
  "frameset",
  "head",
  "header",
  "h1",
  "h2",
  "h3",
  "h4",
  "h5",
  "h6",
  "hr",
  "html",
  "i",
  "iframe",
  "img",
  "input",
  "ins",
  "kbd",
  "label",
  "legend",
  "li",
  "link",
  "main",
  "map",
  "mark",
  "meta",
  "meter",
  "nav",
  "nobr",
  "noscript",
  "object",
  "ol",
  "optgroup",
  "option",
  "output",
  "p",
  "param",
  "pre",
  "progress",
  "q",
  "s",
  "samp",
  "script",
  "section",
  "select",
  "small",
  "source",
  "span",
  "strike",
  "strong",
  "style",
  "sub",
  "summary",
  "sup",
  "table",
  "tbody",
  "td",
  "template",
  "textarea",
  "tfoot",
  "th",
  "thead",
  "time",
  "title",
  "tr",
  "u",
  "ul",
  "var",
  "video",
  "wbr",
  "xmp",
].forEach(tagname=>{
	mk[tagname] = (...args) => mk(tagname, ...args);
});

function* nodesFromChildList(children) {
	for(const child of children.flat(Infinity)) {
		if(child instanceof Node) {
			yield child;
		} else {
			yield new Text(child);
		}
	}
}
function append(el, ...children) {
	for(const child of nodesFromChildList(children)) {
		if(el instanceof Node) el.appendChild(child);
		else el.push(child);
	}
	return el;
}

function insertAfter(el, ...children) {
	for(const child of nodesFromChildList(children)) {
		el.parentNode.insertBefore(child, el.nextSibling);
	}
	return el;
}

function clearContents(el) {
	el.innerHTML = "";
	return el;
}

function parseHTML(markup) {
	if(markup.toLowerCase().trim().indexOf('<!doctype') === 0) {
		const doc = document.implementation.createHTMLDocument("");
		doc.documentElement.innerHTML = markup;
		return doc;
	} else {
		const el = mk.template({});
		el.innerHTML = markup;
		return el.content;
	}
}</script>